package com.sig.util;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 反射工具
 *
 * @author sig
 * @since 2019/2/26
 */
public final class ReflectUtil {

    private ReflectUtil() {
    }

    /**
     * 获取字段实例值，包括多层继承的父类
     *
     * @param src
     * @param fieldName
     * @return
     */
    public static Object getFieldObject(final Object src, final String fieldName) {
        if (src == null || StringUtils.isBlank(fieldName))
            return null;
        Class<?> clazz = src.getClass();
        while (clazz != null && clazz != Object.class) {
            for (Field field : clazz.getDeclaredFields()) {
                if (!fieldName.equalsIgnoreCase(field.getName()))
                    continue;
                field.setAccessible(true);
                try {
                    return field.get(src);
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }
            clazz = clazz.getSuperclass();
        }
        return null;
    }

    /**
     * 给字段实例赋值，包括多层继承的父类
     *
     * @param src
     * @param fieldName
     * @param fieldValue
     */
    public static void setFieldObject(final Object src, final String fieldName, final Object fieldValue) {
        if (src == null || StringUtils.isBlank(fieldName))
            return;
        Class<?> clazz = src.getClass();
        while (clazz != null && clazz != Object.class) {
            for (Field field : clazz.getDeclaredFields()) {
                if (!fieldName.equalsIgnoreCase(field.getName()))
                    continue;
                field.setAccessible(true);
                try {
                    field.set(src, ConvertUtils.convert(fieldValue, field.getType()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            clazz = clazz.getSuperclass();
        }
    }

    /**
     * 获取对象定义的所有字段，包括多层继承的父类
     *
     * @param src
     * @return
     */
    public static List<Field> getFields(final Object src) {
        if (src == null)
            return Collections.emptyList();
        List<Field> list = new ArrayList<>();
        Class<?> clazz = src.getClass();
        while (clazz != null && clazz != Object.class) {
            for (Field field : clazz.getDeclaredFields()) {
                field.setAccessible(true);
                try {
                    list.add(field);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            clazz = clazz.getSuperclass();
        }
        return list;
    }
}
